#define PUDGE_META_LAZY_SPEC BOOST_PP_ITERATION()
 
//template<class T0,class T1>
//bound<tuple<typename param<T0>::type,typename param<T1>::type>> operator()(T0 & t0, T1 & t1)
//{
//	typedef tuple<typename param<T0>::type,typename param<T1>::type> tuple_type;
//	return bound<tuple_type>(function_, tuple_type( param<T0>()(t0), param<T1>()(t1) ));
//}

#define PUDGE_META_LAZY_STOREP(Z,N,D) typename param<T ## N>::type
#define PUDGE_META_LAZY_ARG(Z,N,D) T ## N & t ## N
#define PUDGE_META_LAZY_PARAM(Z,N,D) param<T ## N>()(t ## N)

template<BOOST_PP_ENUM_PARAMS(PUDGE_META_LAZY_SPEC, class T)>
bound<tuple<BOOST_PP_ENUM(PUDGE_META_LAZY_SPEC, PUDGE_META_LAZY_STOREP,)>> operator()
	(BOOST_PP_ENUM(PUDGE_META_LAZY_SPEC, PUDGE_META_LAZY_ARG,))
{
	typedef tuple<BOOST_PP_ENUM(PUDGE_META_LAZY_SPEC, PUDGE_META_LAZY_STOREP,)> tuple_type;
	return bound<tuple_type>(function_, tuple_type(BOOST_PP_ENUM(PUDGE_META_LAZY_SPEC, PUDGE_META_LAZY_PARAM,)));
}

template<BOOST_PP_ENUM_PARAMS(PUDGE_META_LAZY_SPEC, class T)>
bound<tuple<BOOST_PP_ENUM(PUDGE_META_LAZY_SPEC, PUDGE_META_LAZY_STOREP,)>> operator() 
	(BOOST_PP_ENUM(PUDGE_META_LAZY_SPEC, PUDGE_META_LAZY_ARG,)) const
{
	typedef tuple<BOOST_PP_ENUM(PUDGE_META_LAZY_SPEC, PUDGE_META_LAZY_STOREP,)> tuple_type;
	return bound<tuple_type>(function_, tuple_type(BOOST_PP_ENUM(PUDGE_META_LAZY_SPEC, PUDGE_META_LAZY_PARAM,)));
}

//template<class T0, class T1, class Args> 
//struct call<tuple<T0,T1>, Args>
//{
//	typedef Args args_type;
//	typedef tuple<T0,T1> stored_type;
//	typedef typename Function::result
//		<	typename extract<T0, Args>::result_type
//		,	typename extract<T1, Args>::result_type>::type result_type;
//
//	result_type operator()(Function & f, stored_type & stored, args_type & args) const
//	{
//		return f
//			(	extract<T0,Args>()(tuple_element<0>()(stored), args)
//			,	extract<T1,Args>()(tuple_element<1>()(stored), args));
//	}
//};

#define PUDGE_META_LAZY_CRESULT(Z,N,D) typename extract<T ## N, Args>::result_type
#define PUDGE_META_LAZY_EXTRACT(Z,N,D) extract<T ## N,Args>()(tuple_element<N>()(stored), args)

template<BOOST_PP_ENUM_PARAMS(PUDGE_META_LAZY_SPEC, class T), class Args>
struct call<tuple<BOOST_PP_ENUM_PARAMS(PUDGE_META_LAZY_SPEC, T)>, Args>
{
	typedef Args args_type;
	typedef tuple<BOOST_PP_ENUM_PARAMS(PUDGE_META_LAZY_SPEC, T)> stored_type;
	typedef typename Function::result
		<	BOOST_PP_ENUM(PUDGE_META_LAZY_SPEC, PUDGE_META_LAZY_CRESULT,) >::type result_type;

	result_type operator()(Function & f, stored_type & stored, args_type & args) const
	{
		return f(BOOST_PP_ENUM(PUDGE_META_LAZY_SPEC, PUDGE_META_LAZY_EXTRACT,) );
	}
};
